#ifndef HISEC_SCQ_H
#define HISEC_SCQ_H

#include "typedef.h"
#include "hisec_cmd.h"

#define HISEC_SCQE_SIZE 64

/* shared complete queue info struct */
typedef struct hisec_scq_info {
#if (BYTE_ORDER == LITTLE_ENDIAN)
    u64 pcie_template_hi : 3;
    u64 pbit2 : 1;
    u64 cur_cqe_gpa : 60;
#else
    u64 cur_cqe_gpa : 60;
    u64 pbit2 : 1;
    u64 pcie_template_hi : 3;
#endif

#if (BYTE_ORDER == LITTLE_ENDIAN)
    u64 pi : 15;
    u64 pi_o : 1;
    u64 ci : 15;
    u64 ci_o : 1;
    u64 c_eqn_msi_x : 10;
    u64 pbit1 : 1;
    u64 ci_type : 1;
    u64 cq_depth : 3;
    u64 armq : 1;
    u64 cur_cqe_cnt : 8;
    u64 cqe_max_cnt : 8;
#else
    u64 cqe_max_cnt : 8;
    u64 cur_cqe_cnt : 8;
    u64 armq : 1;
    u64 cq_depth : 3;
    u64 ci_type : 1;
    u64 pbit1 : 1;
    u64 c_eqn_msi_x : 10;
    u64 ci_o : 1;
    u64 ci : 15;
    u64 pi_o : 1;
    u64 pi : 15;
#endif

#if (BYTE_ORDER == LITTLE_ENDIAN)
    u64 cqe_dmaattr_idx : 6;
    u64 cq_so_ro : 2;
    u64 init_mode : 2;
    u64 next_o : 1;
    u64 loop_o : 1;
    u64 next_cq_wqe_page_gpa : 52;
#else
    u64 next_cq_wqe_page_gpa : 52;
    u64 loop_o : 1;
    u64 next_o : 1;
    u64 init_mode : 2;
    u64 cq_so_ro : 2;
    u64 cqe_dmaattr_idx : 6;
#endif

#if (BYTE_ORDER == LITTLE_ENDIAN)
    u64 pcie_template_lo : 3;
    u64 pbit0 : 1;
    u64 ci_gpa : 60;
#else
    u64 ci_gpa : 60;
    u64 pbit0 : 1;
    u64 pcie_template_lo : 3;
#endif
} hisec_scq_info_s;

enum hisec_scqe_msg_type_e {
    HISEC_SCQE_MSG_DH_RESULT_RSP = 0,
    HISEC_SCQE_MSG_SA_AGING_UPDATE,
    HISEC_SCQE_MSG_MAX,
};

typedef struct hisec_cqe_comm_hdr {
    union {
        struct {
#if (BYTE_ORDER == LITTLE_ENDIAN)
            u32 rsvd0 : 8;
            u32 channel_id : 8;
            u32 op_code : 8;
            u32 rsp_state : 7;
            u32 ownership : 1;
#else
            u32 ownership : 1;
            u32 rsp_state : 7; /* 0:success, 1:fail */
            u32 op_code : 8;   /* hisec_scqe_msg_type_e */
            u32 channel_id : 8;
            u32 rsvd0 : 8;
#endif
        } bs;
        u32 value;
    } dw0;

    u32 cmd_sn;
    u32 rsvd1[2];
} hisec_cqe_comm_hdr_s;

typedef struct hisec_task_rsp_cqe {
    hisec_cqe_comm_hdr_s cqe_hdr;

    u32 result_vah;
    u32 result_val;
    u32 magic_h;
    u32 magic_l;

    u32 result_len;
    u32 rsvd[5];
    u32 crcvh;
    u32 crcvl;
} hisec_task_rsp_cqe_s;

typedef struct hisec_sa_aging_update {
    hisec_cqe_comm_hdr_s cqe_hdr;

    hisec_sa_tuples_s tuples;

    u32 rsvd[4];
} hisec_sa_aging_update_s;

#endif /* HISEC_SCQ_H */